package idao;

/**
 * This is the central class for working with IDAO, implementation is thread
 * safe. Client uses this class to get instances of the dao interface and, if
 * client runs as a standalone application outside of JEE container, to control
 * transactions.
 * <p>
 * The following example demonstrates common use of IDAO.
 * 
 * <pre>
 * &#064;code standalone application
 * 
 *  DataSource ds = ... // get data source from wherever appropriate
 *  IDAO iDao = IDAOFactory.newIDAO(ds);
 *  SomeDaoInterface someDao = iDao.newDao(SomeDaoInterface.class);
 *  try {
 *     iDao.startTransaction();
 *     // do some stuff with someDao
 *     iDao.commitTransaction();
 *  } finally {
 *     iDao.endTransaction();
 *  }
 * }
 * </pre>
 * 
 * <pre>
 * &#064;code global transaction context
 * 
 *  DataSource ds = ... // get container provided datasource by JNDI
 *  IDAO iDao = IDAOFactory.newIDAO(ds);
 *  SomeDaoInterface someDao = iDao.newDao(SomeDaoInterface.class);
 *  // do some stuff with someDao
 * }
 * </pre>
 * 
 * @author huhao
 */
public interface IDAO
{

    /**
     * Create a new instance for the given dao interface.
     * 
     * @param <I>
     *        the type of dao
     * @param dao
     *        the dao interface class
     * @return the newly created dao instance
     * @throws DaoRuntimeException
     *         if an error occurs while creating dao instance
     * @throws IllegalArgumentException
     *         if the given dao class is not an interface
     */
    public <I> I newDao(Class<? extends I> dao) throws DaoRuntimeException;

    /**
     * Demarcates the beginning of a transaction scope. Transactions must be
     * properly committed or rolled back to be effective. Always call
     * endTransaction() once startTransaction() has been called.
     * 
     * @throws DaoRuntimeException
     *         If an error occurs while starting the transaction
     * @throws IllegalStateException
     *         If a transaction already existed
     */
    public void startTransaction() throws DaoRuntimeException;

    /**
     * Commits the currently started transaction.
     * 
     * @throws DaoRuntimeException
     *         If an error occurs while committing the transaction
     * @throws IllegalStateException
     *         If no transaction existed
     */
    public void commitTransaction() throws DaoRuntimeException;

    /**
     * Ends the current transaction and rolls back if necessary. If the
     * transaction has been started, but not committed, it will be rolled back
     * upon calling endTransaction(). Will do nothing if no transaction has been
     * started yet.
     * 
     * @throws DaoRuntimeException
     *         If an error occurs while ending the transaction
     */
    public void endTransaction() throws DaoRuntimeException;
}
